#include <iostream>

using namespace std;

struct A 
{
	A(int) {}
	operator bool() const { return true; }
};

struct B 
{
	explicit B(int) {}
	explicit operator bool() const { return true; }
};

void doA(A a) {}

void doB(B b) {}

void test1()
{
	A a1(1);     // OK：直接初始化
	A a2 = 1;    // OK：复制初始化
	A a3{ 1 };     // OK：直接列表初始化
	A a4 = { 1 };  // OK：复制列表初始化
	A a5 = (A)1; // OK：允许 static_cast 的显式转换
	doA(1);      // OK：允许从 int 到 A 的隐式转换
	if (a1)
		; // OK：使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
	bool a6(a1); // OK：使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
	bool a7 = a1; // OK：使用转换函数 A::operator bool() 的从 A 到 bool 的隐式转换
	bool a8 = static_cast<bool>(a1); // OK ：static_cast 进行直接初始化

	B b1(1);     // OK：直接初始化
	//    B b2 = 1;        // 错误：被 explicit
	//    修饰构造函数的对象不可以复制初始化
	B b3{ 1 };     // OK：直接列表初始化
	//    B b4 = { 1 };        // 错误：被 explicit
	//    修饰构造函数的对象不可以复制列表初始化
	B b5 = (B)1; // OK：允许 static_cast 的显式转换
	//    doB(1);            // 错误：被 explicit
	//    修饰构造函数的对象不可以从 int 到 B 的隐式转换
	if (b1)
		; // OK：被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B 到 bool
		  // 的按语境转换
	bool b6(b1); // OK：被 explicit 修饰转换函数 B::operator bool() 的对象可以从 B
	// 到 bool 的按语境转换
	//    bool b7 = b1;        // 错误：被 explicit 修饰转换函数
	//    B::operator bool() 的对象不可以隐式转换
	bool b8 = static_cast<bool>(b1); // OK：static_cast 进行直接初始化
}


struct Fraction 
{
	int num; // 分子
	int den; // 分母

	// explicit 修饰的构造函数，防止从 int 或 int,int 到 Fraction 的隐式转换和复制初始化
	explicit Fraction(int n, int d = 1) : num(n), den(d) {}

	// explicit 修饰的转换函数，防止从 Fraction 到 double 的隐式转换
	explicit operator double() const { return static_cast<double>(num) / den; }
};

void test2()
{

	Fraction f1(1, 2); // OK：直接初始化
	//		Fraction f2 = 1;        // 错误：被 explicit 修饰的构造函数不可以复制初始化
	//		Fraction f3 = 1, 2;     // 错误：被 explicit 修饰的构造函数不可以复制初始化
	Fraction f4{ 1, 2 }; // OK：直接列表初始化
	//		Fraction f5 = { 1, 2 };	// 错误：被 explicit 修饰的构造函数不可以复制列表初始化
	Fraction f6 = (Fraction)1;	// OK：允许 static_cast 的显式转换
	Fraction f7 = static_cast<Fraction>(1); // OK：static_cast 进行直接初始化

	//		double d1 = f1; // 错误：被 explicit 修饰的转换函数不可以隐式转换
	double d2(f1);  // OK：被 explicit 修饰的转换函数可以按语境转换
	double d3 = static_cast<double>(f1); // OK：static_cast 进行直接初始化
}

int main() {
	

	return 0;
}